/* p6_4: external interrupt on both edges */
/* PORTD6 is configured to trigger interrupt by both edges. In the interrupt handler, the green LED (PF3) is toggled. The green LED should have the same frequency of the input signal at PORTD6. */
/* Notice in Table 6-7, IRQ3 is assigned to PORTD */

#include "TM4C123GH6PM.h"

int main(void)
{
    SYSCTL->RCGCGPIO |= 0x20;   /* enable clock to PORTF */
    SYSCTL->RCGCGPIO |= 0x08;   /* enable clock to PORTD */
    
    /* configure PORTF for LED output */
    GPIOF->DIR |= 0x0E;         /* make PORTF3, 2, 1 output for LEDs */
    GPIOF->DEN |= 0x0E;         /* make PORTF4-0 digital pins */
    
    /* configure PORTD6 for falling edge trigger interrupt */
    GPIOD->DIR &= ~0x40;        /* make PORTD6 input pin */
    GPIOD->DEN |= 0x40;         /* make PORTD6 digital pin */
    GPIOD->IS  &= ~0x40;        /* make bit 4, 0 edge sensitive */
    GPIOD->IBE |= 0x40;         /* trigger on both edges */
    GPIOD->ICR |= 0x40;         /* clear any prior interrupt */
    GPIOD->IM  |= 0x40;         /* unmask interrupt */
    
    /* enable interrupt in NVIC and set priority to 6 */
    NVIC->IP[3] = 6 << 5;       /* set interrupt priority to 6 */
    NVIC->ISER[0] |= 0x00000008;  /* enable IRQ3 for PORTD */

    __enable_irq(); /* global enable IRQs */

    while(1)
    {   /* wait for interrupts */
    }
}

void GPIOD_Handler(void)
{
    volatile int readback;
    
    GPIOF->DATA ^= 8;           /* toggle green LED */
    GPIOD->ICR |= 0x40;         /* clear the interrupt flag */
    readback = GPIOD->ICR;      /* a read to force clearing of interrupt flag */
}

/* This function is called by the startup assembly code to perform system specific initialization tasks. */
void SystemInit(void)
{
    __disable_irq();    /* disable all IRQs */
    
    /* Grant coprocessor access */
    /* This is required since TM4C123G has a floating point coprocessor */
    SCB->CPACR |= 0x00F00000;
}